//
//  UINavigationController+SafePush.m
//  objective_c_language
//
//  Created by 王玉龙 on 2018/6/20.
//  Copyright © 2018年 longlong. All rights reserved.
//

#import "UINavigationController+SafePush.h"
#import "NSObject+Swizzling.h"
#import <objc/runtime.h>


@implementation UIViewController (SafeTransitionLock)

+ (void)load
{
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        [self methodSwizzlingWithOriginalSelector:@selector(viewDidAppear:) bySwizzledSelector:@selector(safeViewDidAppear:)];
    });
}

- (void)safeViewDidAppear:(BOOL)animated
{
    self.navigationController.viewTransitionInProgress = NO;
    [self safeViewDidAppear:animated];
}

@end


@implementation UINavigationController (SafePush)

+ (void)load
{
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        [self methodSwizzlingWithOriginalSelector:@selector(pushViewController:animated:) bySwizzledSelector:@selector(safePushViewController:animated:)];
        [self methodSwizzlingWithOriginalSelector:@selector(popViewControllerAnimated:) bySwizzledSelector:@selector(safePopViewControllerAnimated:)];
        [self methodSwizzlingWithOriginalSelector:@selector(popToRootViewControllerAnimated:) bySwizzledSelector:@selector(safePopToRootViewControllerAnimated:)];
        [self methodSwizzlingWithOriginalSelector:@selector(popToViewController:animated:) bySwizzledSelector:@selector(safePopToViewController:animated:)];
    });
    
}

- (void)setViewTransitionInProgress:(BOOL)viewTransitionInProgress
{
    NSNumber *number = [NSNumber numberWithBool:viewTransitionInProgress];
    objc_setAssociatedObject(self, @selector(viewTransitionInProgress), number, OBJC_ASSOCIATION_RETAIN);
}

- (BOOL)viewTransitionInProgress
{
    NSNumber *number = objc_getAssociatedObject(self, @selector(viewTransitionInProgress));
    return [number boolValue];
}


#pragma mark - Intercept Pop, Push, PopToRootVC

/// @name Intercept Pop, Push, PopToRootVC

- (NSArray *)safePopToRootViewControllerAnimated:(BOOL)animated
{
    if (self.viewTransitionInProgress)
    {
        return nil;
    }
    
    if(animated)
    {
        self.viewTransitionInProgress = YES;
    }
    NSArray *viewControllers = [self safePopToRootViewControllerAnimated:animated];
    
    if (viewControllers.count == 0)
    {
        self.viewTransitionInProgress = NO;
    }
    
    return viewControllers;
}

- (NSArray *)safePopToViewController:(UIViewController *)viewController animated:(BOOL)animated
{
    if(self.viewTransitionInProgress)
    {
        return nil;
    }
    if(animated)
    {
        self.viewTransitionInProgress = YES;
    }
    
    NSArray *viewControllers = [self safePopToViewController:viewController animated:animated];
    if (viewControllers.count == 0)
    {
        self.viewTransitionInProgress = NO;
    }
    return viewControllers;
}

- (UIViewController *)safePopViewControllerAnimated:(BOOL)animated
{
    if(self.viewTransitionInProgress)
    {
        return nil;
    }
    if(animated)
    {
        self.viewTransitionInProgress = YES;
    }
    UIViewController *viewController = [self safePopViewControllerAnimated:animated];
    if (viewController == nil)
    {
        self.viewTransitionInProgress = NO;
    }
    return viewController;
}

- (void)safePushViewController:(UIViewController *)viewController animated:(BOOL)animated
{
    self.delegate = self;
    if(self.viewTransitionInProgress == NO)
    {
        [self safePushViewController:viewController animated:animated];
        if(animated)
        {
            self.viewTransitionInProgress =YES;
        }
    }
}

//- (void)safeDidShowViewController:(UIViewController *)viewController animated:(BOOL)animated
//{
//    [self safeDidShowViewController:viewController animated:animated];
//    self.viewTransitionInProgress = NO;
//}
//
//- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated
//{
//    id tc = navigationController.topViewController.transitionCoordinator;
//    [tc notifyWhenInteractionEndsUsingBlock:^(id context)
//    {
//        self.viewTransitionInProgress = NO;
//        self.interactivePopGestureRecognizer.delegate = (id)viewController;
//        [self.interactivePopGestureRecognizer setEnabled:YES];
//    }];
//    if(navigationController.delegate != self)
//    {
//        [navigationController.delegate navigationController:navigationController willShowViewController:viewController animated:animated];
//    }
//}

@end
